﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace Compilador.Lexico
{
    public class TokenLexico
    {
        #region Deftokens
        //Enumerador que contiene todos los tipos de token aceptados por el lenguaje.
        public enum TokenType
        {
            [DescriptionAttribute("lambda")]
            Vacio,

            Error,

            [DescriptionAttribute("$")]
            EOF,

            [DescriptionAttribute(";")]
            EndLine, // ;
            /// <summary>
            /// EMPIEZA PARTE DEL WHILE
            /// </summary>
            [DescriptionAttribute("while")]
            WhileStart, // while
            [DescriptionAttribute("do")]
            WhileDo, // do
            [DescriptionAttribute("end-while")]
            WhileEnd, // end-while
            /// <summary>
            ///FIN PARTE DEL WHILE
            /// </summary>

            /// <summary>
            ///EMPIEZA PARTE DEL IF
            /// </summary>
            [DescriptionAttribute("if")]
            IfStart, // condicion If
            [DescriptionAttribute("then")]
            IfThen, // Sentencia then 
            [DescriptionAttribute("else")]
            IfElse, // Sentencia else 
            [DescriptionAttribute("end-if")]
            IfEnd, // Sentencia end-if 
            /// <summary>
            /// FIN PARTE DEL IF
            /// </summary>
            /// <summary>
            /// EMPIEZA PARTE DE PROCEDIMIENTOS Y FUNCIONES
            /// </summary>
            [DescriptionAttribute("main")]
            Main, //Procedimiento Main
            [DescriptionAttribute("procedure")]
            ProcedureStart, //Empieza Procedimiento
            [DescriptionAttribute("end-proc")]
            ProcedureEnd, //Fin procedimiento

            [DescriptionAttribute("function")]
            FunctionStart, //Empieza Funcion
            [DescriptionAttribute("end-func")]
            FunctionEnd, //Fin Funcion
            [DescriptionAttribute("begin")]
            Begin, //comenzar
            [DescriptionAttribute("byval")]
            Byval, //pasaje de parametros por valor
            [DescriptionAttribute("byref")]
            Byref, //pasajde parametros por referencia
            /// <summary>
            /// FIN PART DE PROCEDIMIENTOS Y FUNCIONES
            /// </summary>

            /// <summary>
            /// EMPIEZA PARA DEFINIR VARIABLE
            /// </summary>
            [DescriptionAttribute("const")]
            Const, //const
            [DescriptionAttribute("var")]
            Var, //var
            /// <summary>
            /// FIN PARA DEFINIR VARIABLE
            /// </summary>
            [DescriptionAttribute("read")]
            Read, //leer

            [DescriptionAttribute("id")]
            Identificador, //variable formada con una letra inicial y despues numeros o letras
            /// <summary>
            /// EMPIEZA TIPO DE DATO
            /// </summary>
            [DescriptionAttribute("nat")]
            NumberNatural,
            [DescriptionAttribute("int")]
            NumberInteger,

            [DescriptionAttribute(":")]
            TipoDato, // :

            [DescriptionAttribute("natural")]
            TypeNatural, //natural 
            [DescriptionAttribute("integer")]
            TypeInteger, //entero

            /// <summary>
            /// FIN TIPO DATO
            /// </summary>
            /// EMPIEZA FUNCIONES CONVERSION
            /// 
            [DescriptionAttribute("tonatural")]
            ToNatural,
            [DescriptionAttribute("tointeger")]
            ToInteger,
            /// <summary>
            /// FIN FUNCIONES CONVERSION
            /// </summary>
            /// EMPIEZA FUNCIONES PAR/IMPAR
            [DescriptionAttribute("odd")]
            IsOdd,
            [DescriptionAttribute("even")]
            IsEven,
            /// <summary>
            /// FIN FUNCIONES PAR/IMPAR
            /// </summary>
            /// EMPIEZA PROCEDIMIENTOS DE MUESTRA
            [DescriptionAttribute("show")]
            Show,
            [DescriptionAttribute("showln")]
            ShowLn,
            /// <summary>
            /// FIN PROCEDIMIENTOS DE MUESTRA
            /// </summary>
            /// EMPIEZA SIMBOLOS
            [DescriptionAttribute(":=")]
            Asignacion, // :=
            [DescriptionAttribute("++")]
            SumaNatural, // ++
            [DescriptionAttribute("--")]
            RestaNatural, // --
            [DescriptionAttribute("**")]
            MultiplicacionNatural, // **
            [DescriptionAttribute("//")]
            DivisionNatural, // //
            [DescriptionAttribute("+")]
            SumaEntero, // +
            [DescriptionAttribute("-")]
            RestaEntero, // -
            [DescriptionAttribute("*")]
            MultiplicacionEntero, // *
            [DescriptionAttribute("/")]
            DivisionEntero, // /
            /// <summary>
            /// FIN SIMBOLOS
            /// </summary>
            /// EMPIEZA COMPARACIONES
            [DescriptionAttribute(">")]
            Mayor, // >
            [DescriptionAttribute(">=")]
            MayorIgual, // >=
            [DescriptionAttribute("=")]
            Igual, // =
            [DescriptionAttribute("<=")]
            MenorIgual, // <=
            [DescriptionAttribute("<")]
            Menor, // <
            [DescriptionAttribute("<>")]
            Distinto, // <>
            /// <summary>
            /// FIN COMPARACIONES
            /// </summary>
            [DescriptionAttribute("(")]
            ParentesisApertura, // (
            [DescriptionAttribute(")")]
            ParentesisClausura, // )
            [DescriptionAttribute("[")]
            CorcheteApertura, // [
            [DescriptionAttribute("]")]
            CorcheteClausura, // ]

            [DescriptionAttribute("literal")]
            Literal, // (
            [DescriptionAttribute(",")]
            Coma, // ,


            [DescriptionAttribute("{")]
            ComentarioApertura, // {
            [DescriptionAttribute("}")]
            ComentarioClausura // }


        }
        #endregion Deftokens
        #region Properties
        /// <summary>
        /// Token Def+Getter+Setter
        /// </summary>
        private TokenType token;
        public TokenType Token
        {
            get { return token; }
            set { token = value; }
        }

        /// <summary>
        /// Lexema Def+Getter+Setter
        /// </summary>
        private String lexema;
        public String Lexema
        {
            get { return lexema; }
            set { lexema = value; }
        }

        /// <summary>
        /// field Def+Getter+Setter
        /// </summary>
        private int field;
        public int Field
        {
            get { return field; }
            set { field = value; }
        }

        /// <summary>
        /// Column Def+Getter+Setter
        /// </summary>
        private int column;
        public int Column
        {
            get { return column; }
            set { column = value; }
        }

        /// <summary>
        /// Description Def+Getter+Setter
        /// </summary>
        private String description;
        public String Description
        {
            get { return description; }
            set { description = value; }
        }

        /// <summary>
        /// Antecedido por separador Def+Getter+Setter
        /// </summary>
        private bool antecedidoPorSeparador;
        public bool AntecedidoPorSeparador
        {
            get { return antecedidoPorSeparador; }
            set { antecedidoPorSeparador = value; }
        }
        #endregion Properties
        /// <summary>
        /// Constructor
        /// </summary>
        public TokenLexico()
        {
            this.description = string.Empty;
            this.token = TokenType.Vacio;
            this.lexema = string.Empty;
        }

        // override object.Equals
        public override bool Equals(object obj)
        {
            //       
            // See the full list of guidelines at
            //   http://go.microsoft.com/fwlink/?LinkID=85237  
            // and also the guidance for operator== at
            //   http://go.microsoft.com/fwlink/?LinkId=85238
            //

            if (obj == null || GetType() != obj.GetType())
            {
                return false;
            }

            // safe because of the GetType check
            TokenLexico comp = (TokenLexico)obj;

            // use this pattern to compare reference members
            if (token == comp.token)
            {
                return true;
            }
            else
            {
                return false;
            }

        }
        public override int GetHashCode() { return 0; }
    }
}
